package com.audiobo.recorder;

import java.awt.*;
import java.io.PrintStream;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.JComponent;

// Referenced classes of package com.audiobo.recorder:
//            VUViewLevelSource

class VUView extends JComponent {

  boolean renderLevels;
  boolean renderTime;
  boolean renderFileExistInfo;
  VUViewLevelSource levelSource;
  Image colourFillImage;
  Image backgroundImage;
  final int refreshIntervalMillis = 40;
  Timer animationTimer;
  int barCount;
  double barHeights[];
  double maxBarHeight;
  int cycleCount;
  short filterFunctions[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
  short animationFunctions[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
  Random random;

  VUView() {
    renderFileExistInfo = false;
    animationTimer = new Timer();
    barCount = 3;
    barHeights = new double[barCount];
    maxBarHeight = 68D;
    cycleCount = 0;
    random = new Random();
    getResources();
    renderLevels = false;
    renderTime = false;
    setDoubleBuffered(true);
    setOpaque(true);
    animationTimer.scheduleAtFixedRate(new TimerTask() {

      public void run() {
        if (renderLevels) {
          repaint(0L, 0, 0, getWidth(), getHeight());
        } else if (renderTime) {
          repaint(0L, 0, 0, getWidth(), getHeight());
        }
      }

    }, 0L, 40L);
  }

  protected void getResources() {
    try {
      colourFillImage = ImageIO.read(getClass().getClassLoader().getResource(
          "resources/VUView/colourfill.png"));
      backgroundImage = ImageIO.read(getClass().getClassLoader().getResource(
          "resources/VUView/recording_background.png"));
    } catch (Exception exception) {
      System.err.println((new StringBuilder())
          .append("exception downloading VUView resources ").append(exception)
          .toString());
    }
  }

  public void setRenderLevels(boolean flag) {
    renderLevels = flag;
    renderTime = flag;
    repaint(0L, 0, 0, getWidth(), getHeight());
  }

  public boolean getRenderLevels() {
    return renderLevels;
  }

  public void setLevelSource(VUViewLevelSource vuviewlevelsource) {
    levelSource = vuviewlevelsource;
  }

  public VUViewLevelSource getLevelSource() {
    return levelSource;
  }

  protected double barHeightFunction(int i, double d, double d1, double d2) {
    if (d1 < 0.01D || i == 0 || i == 8) {
      return maxBarHeight * d1;
    }
    if (i == 1 || i == 7) {
      return maxBarHeight * Math.pow(d1, 0.5D);
    }
    if (i == 2 || i == 6) {
      return maxBarHeight * Math.pow(d1, 0.40000000000000002D);
    }
    if (i == 3 || i == 5) {
      return maxBarHeight * Math.pow(d1, 0.29999999999999999D);
    }
    if (i == 4) {
      return maxBarHeight * Math.pow(d1, 0.20000000000000001D);
    } else {
      System.out.println((new StringBuilder())
          .append("Spurious animation function: ").append(i).toString());
      return d1;
    }
  }

  protected double lowPassFilterFunction(int i, double d, double d1) {
    double d2 = 0.94999999999999996D;
    double d3 = 0.10000000000000001D;
    double d4 = 1.0D;
    double d5 = (d4 - d3) / 8D;
    switch (i) {
    case 5: // '\005'
      d2 = d3 + 5D * d5;
      break;

    case 3: // '\003'
    case 4: // '\004'
    case 6: // '\006'
      d2 = d3 + 4D * d5;
      break;

    case 2: // '\002'
    case 7: // '\007'
      d2 = d3 + 3D * d5;
      break;

    case 1: // '\001'
    case 8: // '\b'
      d2 = d3 + 2D * d5;
      break;

    case 0: // '\0'
      d2 = d3 + 1.0D * d5;
      break;
    }
    return d2 * d1 + (1.0D - d2) * d;
  }

  protected double constrainFunction(double d, double d1, double d2) {
    double d3 = Math.max(d1, d2);
    double d4 = Math.min(d1, d2);
    double d5 = d4 + (d3 - d4) / 2D;
    double d6 = d5 - d;
    d += d6 / 3D;
    return d;
  }

  protected void animationStep() {
    double d = levelSource.getAudioPeak();
    double d1 = levelSource.getAudioLevel();
    double ad[] = new double[barCount];
    if (cycleCount++ % 30 == 0) {
      int i = random.nextInt(barCount);
      int k = random.nextInt(barCount);
      if (i != barCount / 2) {
        filterFunctions[i] = (short) random.nextInt(barCount);
      }
      if (k < barCount / 2 || k > barCount / 2 + 1) {
        animationFunctions[k] = (short) random.nextInt(barCount);
      }
    }
    for (int j = 0; j < barCount; j++) {
      ad[j] = barHeightFunction(animationFunctions[j], barHeights[j], d1, d);
      ad[j] = lowPassFilterFunction(filterFunctions[j], barHeights[j], ad[j]);
      if (j < barCount / 2 || j > barCount / 2) {
        int l = j != 0 ? j - 1 : barCount - 1;
        int i1 = j != barCount - 1 ? j + 1 : 0;
        double d2 = barHeights[l];
        double d3 = barHeights[i1];
        ad[j] = constrainFunction(ad[j], d2, d3);
      }
    }

    barHeights = ad;
  }

  protected Color bgColor() {
    return new Color(29, 29, 29, 255);
  }

  protected void paintComponent(Graphics g) {
    g.setColor(bgColor());
    g.fillRect(0, 0, getWidth(), getHeight());
    if (renderLevels) {
      animationStep();
      for (int i = 0; i < barCount; i++) {
        drawBar(g, i);
      }

    }
    if (backgroundImage != null) {
      g.drawImage(backgroundImage, 0, 0, null);
    }
  }

  protected void drawBar(Graphics g, int i) {
    int j = 32 * i;
    int k = j + 32;
    int l = (int) ((double) getHeight() - barHeights[i]);
    int i1 = getHeight();
    g.drawImage(colourFillImage, j, l, k, i1, j, l, k, i1, null);
    //System.out.println("drawBar" + j + " " + l + " " + k + " " + i1 );
  }
}
